package uk.ac.cam.echo.server;

import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Tom Smith
 */
public class MayBallServer {

	public static final SimpleDateFormat DateFormat = new SimpleDateFormat("[dd/MM/yy HH:mm:ss]");
	
	public static void main(String[] args) {

		try {
			// Port to listen on.
			int port = 44444;
			
			// Create a MayBallServer with a listening socket.
			MayBallServer server = new MayBallServer(port);	
			// Initialize the database.
			server.setDBConnection();
			
			while (true) {
				server.acceptClient();
			}

		} catch (BindException e) {
			System.err.println("Already have a socket bound to this port.");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	private final ServerSocket m_ServerSocket;

	/**
	 * @param port The port to listen for connections on.
	 * @throws SQLException 
	 * @throws IOException 
	 */
	public MayBallServer(int port) throws SQLException, IOException {
		this.m_ServerSocket = new ServerSocket(port);
		System.out.println(MayBallServer.DateFormat.format(new Date()) + " MAY BALL SERVER STARTED. LISTENING ON PORT: " + this.m_ServerSocket.getLocalPort());
	}

	/**
	 * Wait for a client to connect, then give them a handler.
	 * @throws IOException
	 */
	private void acceptClient() throws IOException {
		Socket client = this.m_ServerSocket.accept();
		new ClientHandler(client);
	}

	/**
	 * Set the connection for the Database.
	 * @throws ClassNotFoundException
	 * @throws SQLException
	 */
	private void setDBConnection() throws ClassNotFoundException, SQLException {
		// Load the HSQLDB JDBC driver
		Class.forName("org.hsqldb.jdbc.JDBCDriver" );

		// Get the connection for the HSQLDB driver.
		Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost", "SA", "");

		// Always write data out to disk.
		Statement delayStatement = c.createStatement();
		delayStatement.execute("SET WRITE_DELAY FALSE");
		delayStatement.close();

		Database.setConnection(c);
	}

}
